package com.partsoft.dits.integrate;

import java.io.UnsupportedEncodingException;

import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import com.partsoft.dits.DataDescriptorRegistry;
import com.partsoft.dits.DataEdgeDescriptor;
import com.partsoft.dits.DataIntegrateBatch;
import com.partsoft.dits.DataTransformer;
import com.partsoft.dits.TransformableEdgeDescriptor;
import com.partsoft.dits.message.MessageEntity;
import com.partsoft.dits.transform.TransformException;
import com.partsoft.dits.transform.TransformReactor;

@SuppressWarnings("unchecked")
public abstract class AbstractTableDataTransformer implements DataTransformer {
	
	public abstract DataDescriptorRegistry<TransformableEdgeDescriptor> getDataDescriptorRegistry();
	
	public abstract TransformReactor getTransformReactor();

	public boolean supportData(Class<? extends DataEdgeDescriptor> descriptorClazz) {
		return ClassUtils.isAssignable(TransformableEdgeDescriptor.class, descriptorClazz);
	}

	public boolean supportData(DataEdgeDescriptor dataDescriptor) {
		if (!ClassUtils.isAssignableValue(TransformableEdgeDescriptor.class, dataDescriptor)) return false;
		Assert.notNull(getDataDescriptorRegistry(), "请设置数据描述符注册表。");
		return supportData((Class<? extends DataEdgeDescriptor>) ClassUtils.getUserClass(dataDescriptor)) ?
				getDataDescriptorRegistry().hasDescriptor((TransformableEdgeDescriptor)dataDescriptor) : false;
	}

	public void process(DataIntegrateBatch batch) {
		Assert.notNull(batch);
		Assert.notNull(batch.getDataDescriptor());
		Assert.notNull(batch.getInputParameter());
		Assert.isInstanceOf(MessageEntity.class, batch.getInputParameter(), "处理的输入参数不正确，必须为MessageEntity类型。");
		DataEdgeDescriptor dataDesc = batch.getDataDescriptor();
		MessageEntity msgEntity = (MessageEntity) batch.getInputParameter();
		Assert.isTrue(supportData(dataDesc), String.format("不支持的数据描述符(%s)", dataDesc.toString()));
		try {
			batch.setResult(doProcess((TransformableEdgeDescriptor) dataDesc, msgEntity));
		} catch (Throwable e) {
			batch.setException(e);
		}
	}
	
	protected byte[] doProcess(TransformableEdgeDescriptor dataDescriptor, MessageEntity msgEntity) throws UnsupportedEncodingException, TransformException {
		Assert.notNull(getTransformReactor(), "请设置转换引擎。");
		return getTransformReactor().transform(dataDescriptor.getTransformScript(), msgEntity).toString().getBytes("utf-8");
	}

	public byte[] transform(DataEdgeDescriptor dataDesc, MessageEntity msgEntity) {
		Assert.notNull(dataDesc);
		Assert.notNull(msgEntity);
		Assert.isTrue(supportData(dataDesc), String.format("不支持的数据描述符(%s)", dataDesc.toString()));
		try {
			return doProcess((TransformableEdgeDescriptor) dataDesc, msgEntity);
		} catch (Throwable e) {
			throw new IllegalArgumentException(e);
		}
	}
}
